package sysu.el.graph.undi;

import sysu.el.array.algors.Sig;
import sysu.el.array.ints.ArrInt;
import sysu.el.graph.Edge;
import sysu.el.graph.GTAdjList;
import sysu.el.graph.GraphConstants;

public class UndiGTAdjList extends GTAdjList{

	/* ******************************************************************** */
	/* ************************* Constructors ***************************** */
	/* ******************************************************************** */
	public UndiGTAdjList() {
		super();
	}

	public UndiGTAdjList(int nodeNum) {
		super(nodeNum);
	}


	public UndiGTAdjList(int edgeNum, Edge[] edgeList){
		super();
		this.setupEnvWithEdgeList(edgeNum, edgeList);
		for (int i=0; i<edgeNum; i++){
			this.addEdge(edgeList[i].s, edgeList[i].e);
		}
	}

	public UndiGTAdjList(UndiGTMatrix mat){
		super(mat.getNodeNum());
		for (int i=0; i<this.getNodeNum(); ++i)
			for (int j=i; j<this.getNodeNum(); ++j)
				if (mat.getW(i, j) != GraphConstants.NULL_EDGE){
					this.addEdge(i, j);
				}
	}

	/* ******************************************************************** */
	/* ************************* Auxiliary OP ***************************** */
	/* ******************************************************************** */
	protected void setupEnvWithEdgeList(int edgeNum, Edge[] edgeList){
		int nodeNum = Edge.regulateEdgeList(edgeNum, edgeList) + 1;
		int counter[] = new int[nodeNum];
		for (int i=0; i<edgeNum; i++){
			counter[edgeList[i].s] ++;
			counter[edgeList[i].e] ++;
		}

		for (int i=0; i<nodeNum; i++)
			this.adjNodes[i] = new ArrInt(counter[i]);
	}

	/* ******************************************************************** */
	/* ************************* Interface OP ***************************** */
	/* ******************************************************************** */

	@Override
	public void addEdge(int i, int j) {
		if (i == j)
			this.addEdgePrimitive(i, i);
		else{
			this.addEdgePrimitive(i, j);
			this.addEdgePrimitive(j, i);
		}

		this.edgeNum++;
	}

	public static int calEdgeNum(int len, ArrInt[] arr){
		int c = 0;
		for (int i=0; i<len; i++)
			c += arr[i].counter;

		return c;
	}


	/* ******************************************************************** */
	/* ******************** Interface Members ***************************** */
	/* ******************************************************************** */
	public String toString(){
		StringBuffer sb = new StringBuffer();
		for (int i=0; i<this.getNodeNum(); i++){
			StringBuffer sb1 = Sig.mkStrBuf(this.getDegree(i), this.adjNodes[i].elements(), "\t");
			sb.append(sb1);
			sb.append("\n");
		}
		return new String(sb);
	}
	
}
